使用 new Date
製作日曆
更新
:我後來改寫的更加簡潔,並且抽離成hook
詳情可參考 前端野人
需要注意month
是從0
開始
new Date()
new Date().getMonth
//0 - 11new Date().getFullYear
// 2020程式邏輯:從當下的時間物件取得月份 控制 +1 / -1
所以要先紀錄時間。
const [ today,setTody] = useState(new Date())
const [currentMonth,setCurrentMonth] = useState(today.getMonth)
const [currentMOnth,setCurrentYear] = useState(today.getFullYear)
因為跳至下個月是用數字加減計算,所以要有判斷式判斷是否大於11
或是小於0
因為表示要跳至下一年
或是前一年
const setNextMonth = () =>{
if (currentMonth === 11) {
setCurrentMonth(0)
setCurrentYear(currentYear + 1)
} else {
setCurrentMonth(currentMonth + 1)
}
}
const setPreMonth = () =>{
if (currentMonth === 0) {
setCurrentYear(currentYear - 1)
setCurrentMonth(11)
} else {
setCurrentMonth(currentMonth - 1)
}
}
月曆這部分比較麻煩,我這邊是處理成二維陣列。
我們要顯示每個月的天數,並且要能跟真實的日曆排版一致。
下面程式可以依照年份及月份顯示組合成月曆天數的二維陣列
firstDay
, 為每個月的1號是在星期幾days
, 為一個月的天數。date = 1
, 為每個月的1號。weekNum
,控制每個星期的數量。為什麼days
要用 32 - new Date(year, month, 32).getDate()
原因在於,我們並不知道當月的天數,但我們知道一個月最多只有31天,所以new Date(year, month, 32).getDate()
為下個月的天數,我們再用32 - 下個月多出來的天數
就可以知道這個月的天數。
因為一個日曆的排版可能是4 * 7
或是5 * 7
甚至可能會有6 * 7
我們不知道但,還是必須留空格給日曆排版,所以是用Math.ceil((days + firstDay) / 7)
判斷日曆需要的weekNum
const daysInMonth = (year, month) => {
const firstDay = new Date(year, month).getDay()
const days = 32 - new Date(year, month, 32).getDate()
let date = 1
let daysInMonth = []
let weekNum = (days) => {
return Math.ceil((days + firstDay) / 7)
}
for (let i = 0; i < weekNum(days); i++) {
let week = []
let day = {
date: '',
}
for (let j = 0; j < 7; j++) {
if (i === 0 && j < firstDay) {
week.push(day)
} else if (date > days) {
week.push(day)
} else {
week.push({ ...day, date })
date++
}
}
daysInMonth.push(week)
}
return daysInMonth
}
使用new Date
更新所選擇的日期。
const isSeleted =
calendar.today.getDate() === day.date &&
calendar.today.getMonth() ===
calendar.currentMonth &&
calendar.today.getFullYear() ===
calendar.currentYear
const setSelectDate = () => {
let getDate = new Date(
calendar.currentYear,
calendar.currentMonth,
day.date,
)
calendar.selectToday(getDate)
}
本系列是由參與 Menswalk 時所做的功能邏輯,詳情可持續follow :https://github.com/antijava/menswalk